# -*- coding: utf-8 -*-
"""
 modbus 读取一舟动环数据
"""
import os

from pyModbusTCP.client import ModbusClient
import time
import struct

from logger import loggerDefine
from readConfig import ReadConfig
from RemoteCmd import RemoteCmd
from localCmd import LocalCmd
import sys

"""
配置日志基本信息
"""
logShip = loggerDefine("shipUps", "shipUps.log")

"""
读取配置
"""
conf = ReadConfig()
server_host = conf.get_host("ship", "server_host")
server_port = conf.get_host("ship", "server_port")
# ups运行供电状态
ups_run_staus = conf.get_host("ship", "ups_run_staus")
# 市电电压
shidian_reg_addr1 = conf.get_host("ship", "shidian_reg_addr1")
shidian_reg_addr2 = conf.get_host("ship", "shidian_reg_addr1")
# 电池容量地址
dianchi_vlumes = conf.get_host("ship", "dianchi_vlumes")

# 空调开关机状态
kongtiao_kaoji1 = conf.get_host("ship", "kongtiao_kaoji1")
kongtiao_kaoji2 = conf.get_host("ship", "kongtiao_kaoji2")
kongtiao_kaoji3 = conf.get_host("ship", "kongtiao_kaoji3")
# 空调送风温度
kongtiao_wendu1 = conf.get_host("ship", "kongtiao_wendu1")
kongtiao_wendu2 = conf.get_host("ship", "kongtiao_wendu2")
kongtiao_wendu3 = conf.get_host("ship", "kongtiao_wendu3")

# 控制参数[kongzhi]
# 程序运行获取一舟大屏数据间隔时间，以秒(s)为单位
server_wait = conf.get_host("kongzhi", "server_wait")
# 当程序到达处理条件，在重试的次数（大于1）
count = conf.get_host("kongzhi", "count")

# UPS运行状态值：市电（4.0）、电池、备用发电机(以具体为准)
ups_run_staus_value = conf.get_host("kongzhi", "ups_run_staus_value")

# ups备用电池电量告警值(0-100)
dianchi_vlumes_gaojing = conf.get_host("kongzhi", "dianchi_vlumes_gaojing")

"""
建立ModbusTcp连接
"""
c = ModbusClient(host=server_host, port=int(server_port))
# open or connect TCP to server
c.open()
# uncomment this line to see debug message
# c.debug(True)


def get_data(register_address, numbers=None):
    """
    获取数据
    :param register_address: 寄存器地址
    :param numbers: 读取位数
    :return:寄存器的值
    """
    # 如果numbers为空,默认为2
    if not numbers:
        numbers = 2

    # if open() is ok, read register (modbus function 0x03)
# if c.is_open():
        # read 10 registers at address 0, store result in regs list
        # regs = c.read_holding_registers(0, 10)
        # if success display registers
        # if regs:
        # print("reg ad #0 to 9: "+str(regs))
        # 字符串转换成16进制
    address_id = int(register_address, 16)
    # 读取寄存器的值
    regs1 = c.read_holding_registers(address_id, numbers)
    if regs1:
        value = str(ReadFloat((regs1[0], regs1[1])))
        return value


# 读取浮点数据
def ReadFloat(*args, reverse=False):
    for n, m in args:
        n, m = '%04x' % n, '%04x' % m
    if reverse:
        v = n + m
    else:
        v = m + n
    y_bytes = bytes.fromhex(v)
    y = struct.unpack('!f', y_bytes)[0]
    y = round(y, 6)
    return y


def WriteFloat(value, reverse=False):
    y_bytes = struct.pack('!f', value)
    # y_hex = bytes.hex(y_bytes)
    y_hex = ''.join(['%02x' % i for i in y_bytes])
    n, m = y_hex[:-4], y_hex[-4:]
    n, m = int(n, 16), int(m, 16)
    if reverse:
        v = [n, m]
    else:
        v = [m, n]
    return v


def ReadDint(*args, reverse=False):
    for n, m in args:
        n, m = '%04x' % n, '%04x' % m
    if reverse:
        v = n + m
    else:
        v = m + n
    y_bytes = bytes.fromhex(v)
    y = struct.unpack('!i', y_bytes)[0]
    return y


def WriteDint(value, reverse=False):
    y_bytes = struct.pack('!i', value)
    # y_hex = bytes.hex(y_bytes)
    y_hex = ''.join(['%02x' % i for i in y_bytes])
    n, m = y_hex[:-4], y_hex[-4:]
    n, m = int(n, 16), int(m, 16)
    if reverse:
        v = [n, m]
    else:
        v = [m, n]
    return v


if __name__ == '__main__':

    while True:
        # sleep before next polling
        time.sleep(int(server_wait))
        # print('UPS运行状态 ' + str(get_data(ups_run_staus, 2)))
        # print('市电电压异常1 ' + str(get_data(shidian_reg_addr1, 2)))
        # print('市电电压异常2 ' + str(get_data(shidian_reg_addr2, 2)))
        # print('电池容量 ' + str(get_data(dianchi_vlumes, 2)))
        # print('空调1送风温度 ' + str(get_data(kongtiao_wendu1, 2)))
        # print('空调2送风温度 ' + str(get_data(kongtiao_wendu2, 2)))
        # print('空调3送风温度 ' + str(get_data(kongtiao_wendu3, 2)))

        # 循环次数
        for i in range(int(count) + 1):
            if i == int(count):
                # 判断达到远程关机条件，市电断开且电池放电达到预设值
                if float(get_data(ups_run_staus)) != float(ups_run_staus_value) and float(
                        get_data(dianchi_vlumes)) <= float(dianchi_vlumes_gaojing):
                    logShip.error("UPS运行状态==>: " + str(get_data(ups_run_staus)) + "  市电已经断开")
                    logShip.error('备用电池容量警告剩余==>:  ' + str(get_data(dianchi_vlumes)) + ' %' + '  -->现在执行负载it设备远程命令....')

                    # 执行关闭远程负载服务器linux主机
                    asu = RemoteCmd()
                    asu.readLinuxlist()
                    logShip.error('执行远程负载it设备命令.........成功!!!')

                    # sleep 30s before next
                    time.sleep(30)
                    # 执行本机程序
                    localasu=LocalCmd()
                    localasu.readLocallist()
                    logShip.error('执行本机命令列表.........成功!!!')
                    exit()

            else:
                logShip.info('UPS运行状态==>: ' + str(get_data(ups_run_staus)))
                logShip.info('电池容量剩余==>:  ' + str(get_data(dianchi_vlumes)) + ' %')
                logShip.info(
                    '空调1 开关机状态==>:  ' + str(get_data(kongtiao_kaoji1) )+ " 送风温度为==>:  " + str(get_data(kongtiao_wendu1))+ " ℃")
                logShip.info(
                    '空调2 开关机状态==>:  ' + str(get_data(kongtiao_kaoji2)) + " 送风温度为==>:  " + str(get_data(kongtiao_wendu2)) + " ℃")
                logShip.info(
                    '空调3 开关机状态==>:  ' + str(get_data(kongtiao_kaoji3)) + " 送风温度为==>:  " + str(get_data(kongtiao_wendu3))+ " ℃")
                if float(get_data(ups_run_staus)) != float(ups_run_staus_value):
                    logShip.error("UPS运行状态==>: " + str(get_data(ups_run_staus)) + "市电已经断开")
                if float(get_data(dianchi_vlumes)) <= float(dianchi_vlumes_gaojing):
                    logShip.error('备用电池容量警告==>:  ' + str(get_data(dianchi_vlumes)) + "%")
